<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title> 无缝轮播图</title>
    <style>
        .carousel-container {
            width: 500px;
            height: 300px;
            margin: 20px auto;
            position: relative;
            outline: 10px solid gray;
            overflow: hidden;
        }

        .carousel-list {
            width: 100%;
            height: 100%;
            display: flex;
            position: relative;
            z-index: -1;
        }

        .carousel-item {
            width: 100%;
            /* 取消压缩 */
            flex-shrink: 0;

            /*下面都是为了里面的文字来设置的，不重要*/
            font-size: 50px;
            font-weight: bold;
            display: flex;
            align-items: center;
            justify-content: center;
        }

        .carousel-item-1 {
            background-color: royalblue;
        }

        .carousel-item-2 {
            background-color: greenyellow;
        }

        .carousel-item-3 {
            background-color: aquamarine;
        }

        .carousel-item-4 {
            background-color: hotpink;
        }

        /*    设置箭头*/
        .carousel-arrow {
            position: absolute;
            width: 50px;
            height: 50px;
            background-color: #000;
            top: 125px;
            opacity: 0.2;
            border-radius: 50%;
        }

        .carousel-arrow-left {
            left: 10px;
        }

        .carousel-arrow-right {
            right: 10px;
        }

        /*设置指示器*/
        .indicator {
            position: absolute;
            bottom: 10px;
            left: 50%;
            transform: translateX(-50%);
        }

        .indicator-item {
            width: 10px;
            height: 10px;
            border-radius: 50%;
            border: 1px solid white;
            display: inline-block;
            opacity: 0.7;
        }

        .indicator-active {
            background-color: white;
        }
    </style>
</head>
<body>

<!--外层div容器-->
<div class="carousel-container">
    <!--    轮播区域 一张一张的轮播图片-->
    <div class="carousel-list">
        <div class="carousel-item carousel-item-1">1</div>
        <div class="carousel-item carousel-item-2">2</div>
        <div class="carousel-item carousel-item-3">3</div>
        <div class="carousel-item carousel-item-4">4</div>
    </div>
    <!--    左箭头-->
    <div class="carousel-arrow carousel-arrow-left"></div>
    <!--    右箭头-->
    <div class="carousel-arrow carousel-arrow-right"></div>
    <!--    指示器-->
    <div class="indicator">
        <span class="indicator-item indicator-active"></span>
        <span class="indicator-item"></span>
        <span class="indicator-item"></span>
        <span class="indicator-item"></span>
    </div>
</div>

<script>
    // 获取页面必要的元素
    const carouselDom = {
        carouselList: document.querySelector(".carousel-list"),
        arrowLeft: document.querySelector(".carousel-arrow-left"),
        arrowRight: document.querySelector(".carousel-arrow-right"),
        indicators: document.querySelectorAll(".indicator-item")
    }

    // 当前是第几张图片（索引）
    let currentIndex = 0

    // 轮播图的数量
    const indicatorCount = carouselDom.indicators.length

    function moveTo(index) {
        carouselDom.carouselList.style.transform = `translateX(-${index * 100}%)`
        carouselDom.carouselList.style.transition = 'transform 0.5s'
        // 设置指示器
        carouselDom.indicators.forEach((indicator, i) => {
            indicator.className = i === index ? 'indicator-item indicator-active' : 'indicator-item'
        })
        currentIndex = index
    }

    // 给指示器添加事件
    carouselDom.indicators.forEach((indicator, index) => {
        indicator.onclick = () => {
            moveTo(index)
        }
    })

    // 对图片做一些改动
    function init() {
        // 复制第一个元素(内容)  true表示包含节点的后代也一起复制
        const firstCloned = carouselDom.carouselList.firstElementChild.cloneNode(true)
        // 复制最后一个元素(内容)
        const lastCloned = carouselDom.carouselList.lastElementChild.cloneNode(true)
        // 在第一个元素(位置)的前面添加最后一个元素(内容)
        carouselDom.carouselList.appendChild(firstCloned)
        // 在最后一个元素(位置)的后面添加第一个元素(内容)
        carouselDom.carouselList.insertBefore(lastCloned, carouselDom.carouselList.firstElementChild)
        // 此时第一个元素(位置)变成了最后一个元素(内容)，但是实际第一个元素(内容)要展示为第一个元素(位置)
        // 但是使用下面的这个属性我是没有理解的
        lastCloned.style.marginLeft = '-100%'
    }

    init()

    // 左箭头事件
    function moveLeft() {
        if (currentIndex === 0) {
            // 当前是第一张图片 做无缝滚动
            // 一瞬间要跳到最后一个元素（和当前元素内容相同）,首先要将动画效果清除
            carouselDom.carouselList.style.transition = 'none'
            // 迅速向右边移动图片数量的宽度
            carouselDom.carouselList.style.transform = `translateX(-${indicatorCount * 100}%)`
            // 等待浏览器渲染 强制回流（读取dom的几何属性，位置，尺寸等）
            // 因为在moveTo中又会加上动画效果，所以要在这之前将位置更换完毕，所以随意访问一个几何属性，使其强制回流
            carouselDom.carouselList.clientWidth
            // 此时回到最后一个,就不会有动画样式了
            moveTo(indicatorCount - 1)
        } else {
            // 当前图片减1
            moveTo(currentIndex - 1)
        }
    }

    // 右箭头事件
    function moveRight() {
        if (currentIndex === indicatorCount - 1) {
            // 当前是最后一张图片 做无缝滚动
            // 一瞬间要跳到第一个元素（和当前元素内容相同）,首先要将动画效果清除
            carouselDom.carouselList.style.transition = 'none'
            // 迅速向左边移动图片数量的宽度
            carouselDom.carouselList.style.transform = `translateX(100%)`
            carouselDom.carouselList.clientWidth
            // 此时回到最后一个,就不会有动画样式了
            moveTo(0)
        } else {
            // 当前图片减1
            moveTo(currentIndex + 1)
        }
    }

    carouselDom.arrowLeft.onclick = moveLeft
    carouselDom.arrowRight.onclick = moveRight
</script>
</body>
</html>
